<!-- eslint-disable no-param-reassign -->
<template>
  <a-modal
    v-bind="{ ...attrs }"
    v-if="visibleModel"
    :visible="visibleModel"
    :maskClosable="false"
    :getContainer="getContainer"
    :width="innerWidth || width"
    class="dsxw-custom-modal"
    :class="{ fullscreen: fullscreenModel }"
    :bodyStyle="bodyStyle"
    :confirmLoading="confirmLoading"
    @ok="$emit('ok')"
    @cancel="$emit('cancel')"
  >
    <template #title>
      <slot name="title">{{ title }}</slot>
    </template>
    <template #closeIcon>
      <slot name="closeIcon">
        <div @click.stop class="ant-modal-operate">
          <!-- 如果设置是全屏则不显示缩放图标 -->
          <template v-if="!fullscreen">
            <a-icon
              type="fullscreen"
              @click="setFullscreen"
              v-if="!fullscreenModel"
            />
            <a-icon type="fullscreen-exit" @click="restore" v-else />
          </template>
          <a-icon type="close" @click="closeModal" v-if="!suring"/>
        </div>
      </slot>
    </template>
    <slot>
      <div style="height:100%;">
        ① 窗口可以拖动；
        <br />② 窗口可以通过八个方向改变大小；
        <br />③ 窗口可以最小化、最大化、还原、关闭；
        <br />④ 限制窗口最小宽度/高度。
      </div>
    </slot>
    <template #footer>
      <slot name="footer">
        <a-button cancel :disabled="suring" @click="$emit('cancel')">{{ $t('cancel') }}</a-button>
        <a-button v-if="isOkBtn" type="primary" :loading="suring" @click="$emit('ok')">{{ $t('sure') }}</a-button>
      </slot>
    </template>
  </a-modal>
</template>
<script>
const cursorStyle = {
  top: 'n-resize',
  left: 'w-resize',
  right: 'e-resize',
  bottom: 's-resize',
  topLeft: 'nw-resize',
  topright: 'ne-resize',
  bottomLeft: 'sw-resize',
  bottomRight: 'se-resize',
  auto: 'auto'
}
export default {
  props: {
    visible: {
      type: Boolean,
      default: false
    },
    fullscreen: {
      type: Boolean,
      default: false
    },
    width: {
      type: [Number, String],
      default: 520
    },
    getContainer: {
      type: Function,
      default: () => document.body
    },
    title: {
      type: String,
      default: '标题'
    },
    // 是否正在执行确定
    suring: {
      type: Boolean,
      default: false
    },
    // 是否正在加载内容
    confirmLoading: {
      type: Boolean,
      default: false
    },
    bodyStyle: {
      type: Object,
      default () {
        return {

        }
      }
    },
    attrs: {
      type: Object,
      default () {
        return {}
      }
    },
    destroyOnClose: Boolean,
    // 用于解决多个弹框同时打开还能定位到中间
    modalCls: {
      type: String,
      default: '.dsxw-custom-modal'
    },
    // 是否展示确定按钮，默认展示
    isOkBtn: {
      type: Boolean,
      default: true
    }
  },
  data () {
    return {
      visibleModel: true,
      innerWidth: '',
      fullscreenModel: this.fullscreen,
      inited: false,
      modalWrapRefEl: null
    }
  },
  watch: {
    visible: {
      handler (val) {
        this.visibleModel = val
        if ((val && Object.is(this.inited, false)) || this.destroyOnClose) {
          this.$nextTick(() => {
            this.initDrag()
          })
        }
      },
      immediate: true
    }
  },
  methods: {
    closeModal () {
      if (this.suring) {
        return
      }
      this.visibleModel = false
      this.$emit('cancel')
    },
    restore () {
      this.fullscreenModel = false
      this.$nextTick(() => {
        this.$emit('full', false)
        this.centerModal()
      })
    },
    initDrag () {
      const modalWrapRefEl = document.querySelector(this.modalCls)
      if (!modalWrapRefEl) {
        return
      }
      this.modalWrapRefEl = modalWrapRefEl
      const modalWrapEl = modalWrapRefEl.querySelector('.ant-modal-wrap')
      const modalEl = modalWrapRefEl.querySelector('.ant-modal')
      if (modalWrapEl && modalEl) {
        this.centerModal()
        const headerEl = modalEl.querySelector('.ant-modal-header')
        headerEl && this.registerDragTitle(modalEl, headerEl)
        modalWrapEl.onmousemove = (event) => {
          if (this.fullscreenModel) return
          const left = event.clientX - modalEl.offsetLeft
          const top = event.clientY - modalEl.offsetTop
          const right = event.clientX - modalEl.offsetWidth - modalEl.offsetLeft
          const bottom = event.clientY - modalEl.offsetHeight - modalEl.offsetTop
          const isLeft = left <= 0 && left > -8
          const isTop = top < 5 && top > -8
          const isRight = right >= 0 && right < 8
          const isBottom = bottom > -5 && bottom < 8
          // 向左
          if (isLeft && top > 5 && bottom < -5) {
            modalWrapEl.style.cursor = cursorStyle.left
            // 向上
          } else if (isTop && left > 5 && right < -5) {
            modalWrapEl.style.cursor = cursorStyle.top
            // 向右
          } else if (isRight && top > 5 && bottom < -5) {
            modalWrapEl.style.cursor = cursorStyle.right
            // 向下
          } else if (isBottom && left > 5 && right < -5) {
            modalWrapEl.style.cursor = cursorStyle.bottom
            // 左上角
          } else if (left > -8 && left <= 5 && top <= 5 && top > -8) {
            modalWrapEl.style.cursor = cursorStyle.topLeft
            // 左下角
          } else if (left > -8 && left <= 5 && bottom <= 5 && bottom > -8) {
            modalWrapEl.style.cursor = cursorStyle.bottomLeft
            // 右上角
          } else if (right < 8 && right >= -5 && top <= 5 && top > -8) {
            modalWrapEl.style.cursor = cursorStyle.topright
            // 右下角
          } else if (right < 8 && right >= -5 && bottom <= 5 && bottom > -8) {
            modalWrapEl.style.cursor = cursorStyle.bottomRight
          } else {
            modalWrapEl.style.cursor = cursorStyle.auto
          }
        }
        modalWrapEl.onmousedown = (e) => {
          if (this.fullscreenModel) return
          const iParentTop = modalEl.getBoundingClientRect().top
          const iParentLeft = modalEl.getBoundingClientRect().left
          const disX = e.clientX - iParentLeft
          const disY = e.clientY - iParentTop
          const iParentWidth = modalEl.offsetWidth
          const iParentHeight = modalEl.offsetHeight

          const { cursor } = modalWrapEl.style

          const mousemove = (event) => {
            if (this.fullscreenModel) return
            if (cursor !== cursorStyle.auto) {
              document.body.style.userSelect = 'none'
            }
            // 向左边拖拽
            if (cursor === cursorStyle.left) {
              modalEl.style.left = event.clientX - disX + 'px'
              modalEl.style.width = this.getMinWidth(iParentWidth + iParentLeft - event.clientX) + 'px'
              // 向上边拖拽
            } else if (cursor === cursorStyle.top) {
              modalEl.style.top = event.clientY - disY + 'px'
              modalEl.style.height = iParentHeight + iParentTop - event.clientY + 'px'
              // 向右边拖拽
            } else if (cursor === cursorStyle.right) {
              modalEl.style.width = this.getMinWidth(event.clientX - iParentLeft) + 'px'
              // 向下拖拽
            } else if (cursor === cursorStyle.bottom) {
              modalEl.style.height = event.clientY - iParentTop + 'px'
              // 左上角拖拽
            } else if (cursor === cursorStyle.topLeft) {
              modalEl.style.left = event.clientX - disX + 'px'
              modalEl.style.top = event.clientY - disY + 'px'
              modalEl.style.height = iParentHeight + iParentTop - event.clientY + 'px'
              modalEl.style.width = this.getMinWidth(iParentWidth + iParentLeft - event.clientX) + 'px'
              // 右上角拖拽
            } else if (cursor === cursorStyle.topright) {
              modalEl.style.top = event.clientY - disY + 'px'
              modalEl.style.width = this.getMinWidth((event.clientX - iParentLeft)) + 'px'
              modalEl.style.height = iParentHeight + iParentTop - event.clientY + 'px'
              // 左下角拖拽
            } else if (cursor === cursorStyle.bottomLeft) {
              modalEl.style.left = event.clientX - disX + 'px'
              modalEl.style.width = this.getMinWidth(iParentWidth + iParentLeft - event.clientX) + 'px'
              modalEl.style.height = event.clientY - iParentTop + 'px'
              // 右下角拖拽
            } else if (cursor === cursorStyle.bottomRight) {
              modalEl.style.width = this.getMinWidth(event.clientX - iParentLeft) + 'px'
              modalEl.style.height = event.clientY - iParentTop + 'px'
            }
            this.innerWidth = modalEl.style.width
          }

          const mouseup = () => {
            document.removeEventListener('mousemove', mousemove)
            document.removeEventListener('mouseup', mouseup)
            document.body.style.userSelect = 'auto'
            modalWrapEl.style.cursor = cursorStyle.auto
            this.$emit('changesize', true)
          }

          document.addEventListener('mousemove', mousemove)
          document.addEventListener('mouseup', mouseup)
        }
      }
      this.inited = true
    },
    getMinWidth (nowWidth) {
      const minWidth = 500
      if (nowWidth < 500) {
        return minWidth
      }
      return nowWidth
    },
    registerDragTitle (dragEl, handleEl) {
      // eslint-disable-next-line no-param-reassign
      handleEl.style.cursor = 'move'
      // eslint-disable-next-line no-param-reassign
      handleEl.onmousedown = (e) => {
        if (this.fullscreenModel) return
        document.body.style.userSelect = 'none'
        const disX = e.clientX - dragEl.getBoundingClientRect().left
        const disY = e.clientY - dragEl.getBoundingClientRect().top
        const mousemove = (event) => {
          if (this.fullscreenModel) return
          let iL = event.clientX - disX
          let iT = event.clientY - disY
          const maxL = document.documentElement.clientWidth - dragEl.offsetWidth
          const maxT = document.documentElement.clientHeight - dragEl.offsetHeight

          iL <= 0 && (iL = 0)
          iT <= 0 && (iT = 0)
          iL >= maxL && (iL = maxL)
          iT >= maxT && (iT = maxT)

          // eslint-disable-next-line no-param-reassign
          dragEl.style.left = iL + 'px'
          // eslint-disable-next-line no-param-reassign
          dragEl.style.top = iT + 'px'
        }
        const mouseup = () => {
          document.removeEventListener('mousemove', mousemove)
          document.removeEventListener('mouseup', mouseup)
          document.body.style.userSelect = 'auto'
        }
        document.addEventListener('mousemove', mousemove)
        document.addEventListener('mouseup', mouseup)
      }
    },
    centerModal () {
      this.$nextTick(() => {
        if (!this.modalWrapRefEl) {
          return
        }
        const modalEl = this.modalWrapRefEl.querySelector('.ant-modal')
        if (modalEl && modalEl.getBoundingClientRect().left < 1) {
          modalEl.style.left = ((document.documentElement.clientWidth - modalEl.offsetWidth) / 2) + 'px'
        }
      })
    },
    setFullscreen () {
      this.fullscreenModel = true
      this.$nextTick(() => {
        this.$emit('full', true)
      })
    }
  }
}
</script>
<style lang="less">
.dsxw-custom-modal {
    &.fullscreen {
        .ant-modal {
            top: 0 !important;
            right: 0 !important;
            bottom: 0 !important;
            left: 0 !important;
            width: 100% !important;
            height: 100% !important;
        }
        .ant-modal-content {
            width: 100% !important;
            height: 100% !important;
        }
    }
    .ant-modal {
        position: absolute;
        padding: 0;
        min-height:560px;
        min-width: 660px;
        .ant-modal-close {
            top: 6px;
            right: 6px;
            &:hover,
            &:focus {
                color: rgba(0, 0, 0, 0.45);
            }
            .ant-space-item:hover .anticon,
            .ant-space-item:focus .anticon {
                color: rgba(0, 0, 0, 0.75);
                text-decoration: none;
            }
            .ant-modal-close-x {
                width: 50px;
                height: 50px;
                line-height: 44px;
                .ant-space {
                    width: 100%;
                    height: 100%;
                }
            }
        }
        .ant-modal-content {
            // width: ~'v-bind("props.width")px';
            display: flex;
            flex-direction: column;
            width: 100%;
            height: 100%;
            min-height: 200px;
            min-width: 200px;
            overflow: hidden;
            .ant-modal-body {
                flex: auto;
                overflow: auto;
                height: 100%;
            }
        }
    }
    .ant-modal-body {
      padding-top:10px;
    }
    .ant-modal-operate {
        height: 100%;
        display: flex;
        justify-content:space-around;
        align-items: center;
    }
}
</style>
